import json
import os
from typing import List, Dict, Optional
from datetime import datetime

from .battle_system import BattleSystem
from .arena import Arena


class GameManager:
    def __init__(self):
        self._available_champions = self._initialize_champions()
        self._available_items = self._initialize_items()
        self._battle_system = BattleSystem()
        self._current_arena = None
        self._game_saves = []
        self._save_directory = "saves"
        
        if not os.path.exists(self._save_directory):
            os.makedirs(self._save_directory)
    
    def _initialize_champions(self) -> Dict:
        try:
            from champions.warrior_champions import DragonWarrior, TigerStriker, PhoenixGuardian
            from champions.mage_champions import ThunderMage, IceSorcerer, FireWarlock
            from champions.assassin_champions import ShadowAssassin, WindNinja, PoisonDart
            from champions.support_champions import HealingMonk, ShieldBearer
            
            return {
                "Dragon Warrior": DragonWarrior,
                "Tiger Striker": TigerStriker,
                "Phoenix Guardian": PhoenixGuardian,
                
                "Thunder Mage": ThunderMage,
                "Ice Sorcerer": IceSorcerer,
                "Fire Warlock": FireWarlock,
                
                "Shadow Assassin": ShadowAssassin,
                "Wind Ninja": WindNinja,
                "Poison Dart": PoisonDart,
                
                "Healing Monk": HealingMonk,
                "Shield Bearer": ShieldBearer
            }
        except ImportError as e:
            print(f"Warning: Could not import all champions: {e}")
            return {}
    
    def _initialize_items(self) -> Dict:
        try:
            from items.weapons import DragonSword, TigerClaw, PhoenixBow, ThunderHammer, IceBlade
            from items.armor import DragonArmor, TigerShield, PhoenixRobe, ThunderGuard, IceShield
            from items.accessories import DragonRing, TigerAmulet, PhoenixNecklace, ThunderBracelet, IceCharm, WindTalisman
            
            return {
                "Dragon Sword": DragonSword,
                "Tiger Claw": TigerClaw,
                "Phoenix Bow": PhoenixBow,
                "Thunder Hammer": ThunderHammer,
                "Ice Blade": IceBlade,
                
                "Dragon Armor": DragonArmor,
                "Tiger Shield": TigerShield,
                "Phoenix Robe": PhoenixRobe,
                "Thunder Guard": ThunderGuard,
                "Ice Shield": IceShield,
                
                "Dragon Ring": DragonRing,
                "Tiger Amulet": TigerAmulet,
                "Phoenix Necklace": PhoenixNecklace,
                "Thunder Bracelet": ThunderBracelet,
                "Ice Charm": IceCharm,
                "Wind Talisman": WindTalisman
            }
        except ImportError as e:
            print(f"Warning: Could not import all items: {e}")
            return {}
    
    def get_available_champions(self) -> List[str]:
        return list(self._available_champions.keys())
    
    def get_available_items(self) -> List[str]:
        return list(self._available_items.keys())
    
    def create_champion(self, champion_name: str):
        if champion_name in self._available_champions:
            champion_class = self._available_champions[champion_name]
            return champion_class()
        return None
    
    def create_item(self, item_name: str):
        if item_name in self._available_items:
            item_class = self._available_items[item_name]
            return item_class()
        return None
    
    def start_battle(self, team1, team2, arena_name: str = "Chang'An Arena") -> Dict:
        if not team1 or not team2:
            return {"success": False, "message": "Both teams must have at least one champion"}
        
        self._current_arena = Arena(arena_name)
        
        result = self._battle_system.start_battle(team1, team2, arena_name)
        return result
    
    def execute_battle_turn(self, team1, team2) -> Dict:
        return self._battle_system.execute_turn(team1, team2)
    
    def get_battle_status(self, team1, team2) -> Dict:
        return self._battle_system.get_battle_status(team1, team2)
    
    def is_battle_active(self) -> bool:
        return self._battle_system.is_battle_active()
    
    def get_battle_log(self) -> List[str]:
        return self._battle_system.get_battle_log()
    
    def save_game(self, team1, team2, save_name: str) -> bool:
        try:
            save_data = {
                "timestamp": datetime.now().isoformat(),
                "team1": [self._champion_to_dict(c) for c in team1],
                "team2": [self._champion_to_dict(c) for c in team2],
                "battle_active": self.is_battle_active(),
                "arena": self._current_arena.name if self._current_arena else None
            }
            
            save_path = os.path.join(self._save_directory, f"{save_name}.json")
            with open(save_path, 'w', encoding='utf-8') as f:
                json.dump(save_data, f, indent=2, ensure_ascii=False)
            
            return True
        except Exception as e:
            print(f"Error saving game: {e}")
            return False
    
    def load_game(self, save_name: str) -> Optional[Dict]:
        try:
            save_path = os.path.join(self._save_directory, f"{save_name}.json")
            if not os.path.exists(save_path):
                return None
            
            with open(save_path, 'r', encoding='utf-8') as f:
                save_data = json.load(f)
            
            team1 = [self._dict_to_champion(c_data) for c_data in save_data["team1"]]
            team2 = [self._dict_to_champion(c_data) for c_data in save_data["team2"]]
            
            return {
                "team1": team1,
                "team2": team2,
                "battle_active": save_data.get("battle_active", False),
                "arena": save_data.get("arena", "Chang'An Arena")
            }
        except Exception as e:
            print(f"Error loading game: {e}")
            return None
    
    def get_save_files(self) -> List[str]:
        if not os.path.exists(self._save_directory):
            return []
        
        save_files = []
        for filename in os.listdir(self._save_directory):
            if filename.endswith('.json'):
                save_files.append(filename[:-5]) 
        
        return save_files
    
    def _champion_to_dict(self, champion) -> Dict:
        return {
            "name": champion.name,
            "level": champion.level,
            "health": champion.health,
            "max_health": champion.max_health,
            "mana": champion.mana,
            "max_mana": champion.max_mana,
            "experience": champion._experience,
            "equipped_items": [item.name for item in champion._equipped_items]
        }
    
    def _dict_to_champion(self, champion_data: Dict):
        champion_name = champion_data["name"]
        champion = self.create_champion(champion_name)
        
        if champion:
            champion._level = champion_data.get("level", 1)
            champion._current_health = champion_data.get("health", champion._max_health)
            champion._current_mana = champion_data.get("mana", champion._max_mana)
            champion._experience = champion_data.get("experience", 0)
            
            for item_name in champion_data.get("equipped_items", []):
                item = self.create_item(item_name)
                if item:
                    champion.equip_item(item)
        
        return champion
    
    def get_champion_info(self, champion_name: str) -> Dict:
        if champion_name not in self._available_champions:
            return {}
        
        temp_champion = self.create_champion(champion_name)
        if not temp_champion:
            return {}
        
        return {
            "name": temp_champion.name,
            "type": temp_champion.get_champion_type(),
            "health": temp_champion.max_health,
            "attack": temp_champion.attack,
            "defense": temp_champion.defense,
            "speed": temp_champion.speed,
            "mana": temp_champion.max_mana,
            "abilities": temp_champion.get_abilities()
        }
    
    def get_item_info(self, item_name: str) -> Dict:
        if item_name not in self._available_items:
            return {}
        
        temp_item = self.create_item(item_name)
        if not temp_item:
            return {}
        
        return {
            "name": temp_item.name,
            "type": temp_item.get_item_type(),
            "rarity": temp_item.rarity,
            "description": temp_item.description,
            "stats": temp_item.get_stats(),
            "special_ability": temp_item.get_special_ability()
        }